package cn.cellcom.agent.j2ee;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cellcom.agent.pojo.TUser;
import cn.cellcom.agent.struts.action.Response;
import cn.cellcom.agent.token.TokenEntity;
import cn.cellcom.agent.util.RedisManager;
import cn.cellcom.jar.util.DT;
import cn.cellcom.jar.util.MD5;
import cn.cellcom.jar.util.MyException;

public class ApiFilter implements Filter {

	private Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0;
		String method = request.getParameter("method");
		if (method.equals("getToken")) {
			String authorization = request.getHeader("Authorization");
			String username = request.getHeader("username");
			TokenEntity tk = new TokenEntity();
			if (StringUtils.isBlank(username)) {
				tk.setCode(TokenEntity.NO_USER);
			} else if (authorization == null) {
				tk.setCode(TokenEntity.NO_AUTH);
				Long l = System.currentTimeMillis();
				tk.setTimestamp(l);
				RedisManager.getInstance().getToken().putAndExpireString("timestamp_" + username, String.valueOf(l), 10);
			} else {
				String timestamp = RedisManager.getInstance().getToken().getString("timestamp_" + username);
				try {
					TUser user = (TUser) AgentListener.getStaticDao().myGet("from " + TUser.class.getSimpleName() + " where username=?",
							new String[] { username });
					if (user == null) {
						log.error("Get user[{}] fail", username);
						tk.setCode(TokenEntity.ERROR_USER);
					} else {
						if (!MD5.toMd5(user.getUsername() + user.getPassword() + timestamp).equals(authorization)) {
							log.error("check fail for user[{}] with timestamp[{}]", username, timestamp);
							tk.setCode(TokenEntity.ERROR_AUTH);
						} else {
							String token = null;
							Long validateTime = 0L;
							RedisManager.getInstance().getToken().remove("token_" + user.getUsername());
							RedisManager.getInstance().getToken().remove("dd43f26e49a08e1b4b539cdf4be55205");
							TokenEntity tk2 = RedisManager.getInstance().getToken().getObject("token_" + username, TokenEntity.class);
							if (tk2 == null || tk2.getValidateTime() < System.currentTimeMillis()) {// 如果没有token
								token = MD5.toMd5(user.getOrg() + user.getUsername() + timestamp);
								validateTime = DT.getNextHour(3).getTime();

								tk.setToken(token);
								tk.setValidateTime(validateTime);
								RedisManager.getInstance().getToken().putAndExpireString(token, user.getUsername(), 3600 * 3);
								RedisManager.getInstance().getToken().putObject("token_" + user.getUsername(), tk, 3600 * 3);
								log.info("[{}] create token[{}], validatetime is ", username, token, validateTime);
							} else {
								token = tk2.getToken().substring(1);
								validateTime = tk2.getValidateTime();
								tk.setToken(token);
								tk.setValidateTime(validateTime);
							}
							tk.setCode(TokenEntity.AUTH_OK);
						}
					}
				} catch (MyException e) {
					log.error("Get user[{}] fail", username, e.getException());
					tk.setCode(TokenEntity.ERROR_USER);
				}
			}
			Response.succObject(((HttpServletResponse) arg1), tk);
		} else {
			String token = request.getHeader("X-Token");
			String username = RedisManager.getInstance().getToken().getString(token);
			if (StringUtils.isBlank(username)) {
				Response.err((HttpServletResponse) arg1, "token有误");
			} else {
				TokenEntity tk2 = RedisManager.getInstance().getToken().getObject("token_" + username, TokenEntity.class);
				if (tk2 == null || tk2.getValidateTime() < System.currentTimeMillis()) {
					Response.err((HttpServletResponse) arg1, "token有误");
					log.error("error token[{}] calling ", token);
				} else {
					arg2.doFilter(arg0, arg1);
				}
			}
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

}
